home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C++ / Applications / Nuntius 1.2 / src / Nuntius / UGroupListDoc.cp < prev    next >
Encoding:
Text File  |  1994-03-16  |  8.6 KB  |  384 lines  |  [TEXT/MPS ]

  1. // Copyright © 1992 Peter Speck, speck@dat.ruc.dk. All rights reserved.
  2. // UGroupListDoc.cp
  3.  
  4. #include "UGroupListDoc.h"
  5. #include "UGroupListView.h"
  6. #include "UGroupList.h"
  7. #include "UGroupListCmds.h"
  8. #include "UPrefsDatabase.h"
  9. #include "Tools.h"
  10. #include "UFatalError.h"
  11. #include "StreamTools.h"
  12. #include "UBufferedFileStream.h"
  13. #include "UNewsAppl.h"
  14.  
  15. #include <RsrcGlobals.h>
  16. #include <ErrorGlobals.h>
  17.  
  18. #include <UPrinting.h>
  19.  
  20. #include <ToolUtils.h>
  21. #include <Packages.h>
  22.  
  23. #pragma segment MyGroupList
  24.  
  25. const long kCurrentGroupListFileVersion = 3;
  26. const long kMinGroupListFileVersion = 1;
  27.  
  28. TGroupListDoc::TGroupListDoc()
  29. {
  30. }
  31.  
  32. pascal void TGroupListDoc::Initialize()
  33. {
  34.     inherited::Initialize();
  35. //    fSavePrintInfo = false; // couldn't get it to create a print record...
  36.     fGroupList = nil;
  37.     fGroupListView = nil;
  38.     fGroupListWindow = nil;
  39.     fIdentifier = kGroupListDocFileType;
  40.     fWindowFrame = VRect(0, 0, 0, 0);
  41.     fWasOldFileVersion = false;
  42.     fPeriodicCheck = nil;
  43. }
  44.  
  45. void TGroupListDoc::IGroupListDoc(TFile *itsFile)
  46. {
  47.     inherited::IFileBasedDocument(itsFile, kGroupListDocFileType);
  48.     FailInfo fi;
  49.     if (fi.Try())
  50.     {
  51.         TGroupList *gl = new TGroupList();
  52.         gl->IGroupList(this);
  53.         fGroupList = gl;
  54.         fi.Success();
  55.     }
  56.     else // fail
  57.     {
  58.         Free();
  59.         fi.ReSignal();
  60.     }
  61. }
  62.  
  63. pascal void TGroupListDoc::DoPostMakeViews(Boolean forPrinting)
  64. {
  65.     inherited::DoPostMakeViews(forPrinting);
  66.     TPeriodicCheckNewArticles *pc = new TPeriodicCheckNewArticles();
  67.     pc->IPeriodicCheckNewArticles(this);
  68.     fPeriodicCheck = pc;
  69.     fPeriodicCheck->SetSleep(gPrefs->GetLongPrefs('CNAT') * 60 * 60);
  70. }
  71.  
  72. pascal void TGroupListDoc::DoInitialState()
  73. {
  74.     inherited::DoInitialState();
  75.     fGroupList->DeleteAll();
  76.     SetChangeCount(0);
  77. }
  78.  
  79. pascal void TGroupListDoc::Free()
  80. {
  81.     if (fPeriodicCheck)
  82.     {
  83. #if qDebug
  84.         fprintf(stderr, "Closing fPeriodicCheck\n");
  85.         VerboseIsObject(fPeriodicCheck);
  86. #endif
  87.         fPeriodicCheck->Close();
  88.         fPeriodicCheck->Free(); fPeriodicCheck = nil;
  89.     }
  90.     if (fPeriodicCheck)
  91.         PanicExitToShell("In TGroupListDoc::Free, had fPeriodicCheck");
  92.     FreeIfObject(fGroupList); fGroupList = nil;
  93.     fGroupListView = nil; // view
  94.     inherited::Free();
  95. }
  96.  
  97. pascal void TGroupListDoc::RevertDocument()
  98. {
  99.     inherited::RevertDocument();
  100.     if (fPeriodicCheck)
  101.         fPeriodicCheck->WakeUp();
  102. }
  103.  
  104. pascal void TGroupListDoc::Close()
  105. {
  106.     long changeCount = this->GetChangeCount();
  107.     short poseResult;
  108.     if (changeCount)
  109.     {
  110.         poseResult = PoseSaveDialog();
  111.         if (poseResult == cancel)
  112.             Failure(noErr, messageCancelled);
  113.     }
  114.  
  115.     this->Changed(mClosed,this);
  116.  
  117.     long oldModDate = 0;
  118.     long oldCreateDate = 0;
  119.     
  120.     Boolean onlyWindowPos = false;
  121.     if (fGroupListWindow && !changeCount && fWindowFrame != VRect(0, 0, 0, 0))
  122.     {
  123.         VRect fr;
  124.         fGroupListWindow->GetFrame(fr);
  125.         if (fr != fWindowFrame)
  126.         {
  127.             changeCount++;
  128.             onlyWindowPos = true;
  129.             poseResult = kYesButton;
  130.             TFile *file = fFileHandler->GetFile();
  131.             if (file)
  132.             {
  133.                 oldModDate = file->GetModificationDate();
  134.                 oldCreateDate = file->GetCreationDate();
  135.             }
  136.         }
  137.     }
  138.     if (fPeriodicCheck)
  139.         fPeriodicCheck->Close();
  140.     if (changeCount)
  141.     {
  142.         if (poseResult == kYesButton)
  143.             SaveDocument(cClose);                // Will fail if unable to save 
  144.         else if (poseResult == kNoButton)
  145.             Abandon();
  146.     }
  147.     if (changeCount && onlyWindowPos && oldModDate && oldCreateDate)
  148.     {
  149.         TFile *file = fFileHandler->GetFile();
  150.         if (file)
  151.         {
  152.             file->SetModificationDate(oldModDate);
  153.             file->SetCreationDate(oldCreateDate);
  154.         }
  155.     }
  156.     // Must never be called for a document related to a view in the Clipboard.
  157.     CWindowIterator iter(this);
  158.  
  159.     for (TWindow* aWindow = iter.FirstWindow(); iter.More(); aWindow = iter.NextWindow())
  160.         aWindow->CloseAndFree();
  161. }
  162.  
  163. pascal void TGroupListDoc::ReadDocument(Boolean forPrinting)
  164. {
  165.     inherited::ReadDocument(forPrinting);
  166.     if (fWasOldFileVersion)
  167.         Changed(cGenericCommand, this);
  168. }
  169.  
  170. pascal void TGroupListDoc::DoRead(TFile *aFile, Boolean /* forPrinting */)
  171. {
  172.     FailOSErr(aFile->SetDataMark(0, fsFromStart)); 
  173.     TStream *aStream = NewBufferedFileStream(aFile, 16 * 1024, 0);
  174.     VOLATILE(aStream);
  175.     FailInfo fi;
  176.     if (fi.Try())
  177.     {
  178.         DoReadFile(aStream);
  179.         aStream->Free(); aStream = nil;
  180.         fi.Success();
  181.     }
  182.     else // fail
  183.     {
  184.         FreeIfObject(aStream); aStream = nil;
  185.         fi.ReSignal();
  186.     }
  187. }
  188.  
  189. void TGroupListDoc::DoReadFile(TStream *aStream)
  190. {
  191.     long version = aStream->ReadLong();
  192.     MyStreamCheckVersion(version, kMinGroupListFileVersion, kCurrentGroupListFileVersion, "TGroupListDoc");
  193.     fWasOldFileVersion = version < kCurrentGroupListFileVersion;
  194.     if (version == 1)
  195.         fGroupList->DoIronAgeFormatRead(aStream);
  196.     else
  197.         fGroupList->DoRead(aStream);
  198.     if (version >= 2)
  199.     {
  200.         VRect vr;
  201.         aStream->ReadVRect(vr);
  202.         fWindowFrame = vr;
  203.         if (fGroupListWindow)
  204.         {
  205.             fGroupListWindow->SetFrame(vr, kRedraw);
  206.             fGroupListWindow->ForceOnScreen();
  207.         }
  208.     }
  209.     if (version >= 3)
  210.     {
  211.         if (aStream->ReadBoolean())
  212.         {
  213.             if (!fPrintInfo)
  214.                 fPrintInfo = NewPermHandle(0);
  215.             MyStreamReadHandle(aStream, fPrintInfo);
  216.         }
  217.     }
  218. }
  219.  
  220. pascal void TGroupListDoc::DoWrite(TFile *aFile, Boolean /* forPrinting */)
  221. {
  222.     gNewsAppl->SetNeedCheckFolderMenus();
  223.     FailOSErr(aFile->SetDataMark(0, fsFromStart)); 
  224.     TStream *aStream = NewBufferedFileStream(aFile, 0, 16 * 1024);
  225.     VOLATILE(aStream);
  226.     FailInfo fi;
  227.     if (fi.Try())
  228.     {
  229.         DoWriteFile(aStream);
  230.         aStream->Free(); aStream = nil;
  231.         fi.Success();
  232.     }
  233.     else // fail
  234.     {
  235.         FreeIfObject(aStream); aStream = nil;
  236.         fi.ReSignal();
  237.     }
  238. }
  239.  
  240. void TGroupListDoc::DoWriteFile(TStream *aStream)
  241. {
  242.     aStream->WriteLong(kCurrentGroupListFileVersion);
  243.     fGroupList->DoWrite(aStream);
  244.     VRect vr;
  245.     fGroupListWindow->GetFrame(vr);
  246.     aStream->WriteVRect(vr);
  247.     if (fPrintInfo)
  248.     {
  249.         aStream->WriteBoolean(true);
  250.         MyStreamWriteHandle(aStream, fPrintInfo);
  251.     }
  252.     else
  253.         aStream->WriteBoolean(false);
  254. }
  255.  
  256. pascal void TGroupListDoc::DoNeedDiskSpace(TFile *itsFile, long &dataForkBytes,  long &rsrcForkBytes)
  257. {
  258.     dataForkBytes += 4 * sizeof(long);
  259.     inherited::DoNeedDiskSpace(itsFile, dataForkBytes, rsrcForkBytes);
  260.     fGroupList->DoNeedDiskSpace(dataForkBytes);
  261. }
  262.  
  263. pascal TFile* TGroupListDoc::DoMakeFile(CommandNumber /* itsCommandNumber */)
  264. {
  265.     return gApplication->DoMakeFile(cNewGroupListDoc);
  266. }
  267.  
  268. pascal void TGroupListDoc::DoMakeViews(Boolean /* forPrinting */)
  269. {
  270.     fGroupListWindow = gViewServer->NewTemplateWindow(kGroupListView, this);
  271.     FailNIL(fGroupListWindow);
  272.     fGroupListView = (TGroupListView*) fGroupListWindow->FindSubView(kGroupListViewID);
  273. #if qDebug
  274.     if (!IsObject(fGroupListView))
  275.         ProgramBreak("Missing grouplistView");
  276. #endif
  277.     TStdPrintHandler *aHandler = new TStdPrintHandler;
  278.     aHandler->IStdPrintHandler(this, fGroupListView, !kSquareDots, kFixedSize, !kFixedSize);
  279.  
  280.     CRect maxResize(fGroupListWindow->fResizeLimits);
  281.     maxResize.right = 250; //@@ hack
  282.     fGroupListWindow->SetResizeLimits(maxResize[topLeft], maxResize[botRight]);
  283.  
  284.     if (fWindowFrame != VRect(0, 0, 0, 0))
  285.     {
  286.         VRect vr(fWindowFrame);
  287.         fGroupListWindow->SetFrame(vr, kRedraw);
  288.         fGroupListWindow->fStaggered = true;
  289.     }
  290.     fGroupListView->UpdateList();
  291.     fGroupListWindow->Open();
  292. }
  293.  
  294. pascal void TGroupListDoc::CloseWindow(TWindow* aWindow)
  295. {
  296.     inherited::CloseWindow(aWindow);
  297. }
  298.  
  299. AliasHandle TGroupListDoc::GetAlias()
  300. {
  301.     AliasHandle ah;
  302.     FailOSErr(fFileHandler->GetFile()->GetAlias(ah));
  303.     return ah;
  304. }
  305.  
  306. pascal void TGroupListDoc::Changed(ChangeID theChange, TObject* changedBy)
  307. {
  308.     inherited::Changed(theChange, changedBy);
  309.     if (theChange == cGroupListChange && fPeriodicCheck)
  310.         CheckForNewArticlesNow();
  311. }
  312.  
  313. Boolean TGroupListDoc::IsCheckingForNewArticlesNow()
  314. {
  315.     return fPeriodicCheck->IsBusy();
  316. }
  317.  
  318. void TGroupListDoc::CheckForNewArticlesNow()
  319. {
  320.     fPeriodicCheck->WakeUp();
  321. }
  322.  
  323. pascal void TGroupListDoc::UntitledName(CStr255& noName)
  324. {
  325.     short preInsert;
  326.     short constChars;
  327.     CStr255 num;
  328.  
  329.     MyGetIndString(noName, kGroupListUntitledName);
  330.     if (ParseTitleTemplate(noName, preInsert, constChars))
  331.     {
  332.         NumToString(gNumUntitled, num);
  333.  
  334.         if (SubstituteInTitle(noName, num, preInsert, constChars))
  335.             ++gNumUntitled;
  336.     }
  337. }
  338.  
  339.  
  340. pascal void TGroupListDoc::DoMenuCommand(CommandNumber aCommandNumber)
  341. {
  342.     inherited::DoMenuCommand(aCommandNumber);
  343. }
  344.  
  345. pascal void TGroupListDoc::DoSetupMenus()
  346. {
  347.     inherited::DoSetupMenus();
  348. }
  349.  
  350. pascal void TGroupListDoc::OpenAgain(CommandNumber /* itsCommandNumber */, TDocument * /* openingDoc */)
  351. {
  352.     if (fWindowList)
  353.     {
  354.         TWindow *window = (TWindow *)fWindowList->First();
  355.         if (window)
  356.             window->Select();
  357.     }
  358. }
  359.  
  360. TGroupList *TGroupListDoc::GetGroupList()
  361. {
  362.     return fGroupList;
  363. }
  364.  
  365. TGroupListView *TGroupListDoc::GetGroupListView()
  366. {
  367.     return fGroupListView;
  368. }
  369.  
  370. void TGroupListDoc::SpecifyList(TGroupList *groupList)
  371. {
  372.     CopyDynamicArray(groupList, fGroupList);
  373.     if (fGroupListView)
  374.     {
  375.         fGroupListView->Focus();
  376.         fGroupListView->ForceRedraw();
  377.     }
  378. }
  379.  
  380. void TGroupListDoc::UpdateGroupStatus(const CStr255 &dotName, Boolean hasNewArticles)
  381. {
  382.     fGroupListView->UpdateGroupStatus(dotName, hasNewArticles);
  383. }
  384.